package org.gpp.proj1.bone;

import junit.framework.TestCase;

import com.jme.math.Quaternion;

/**
 * Test case for the Bone class
 * 
 * @author Pablo Diego
 * @author Paolo Victor
 */
public class BoneTest extends TestCase {

	public void testIsChild(){
		
		Bone bone = new Bone("test");
		
		Bone childBone = new Bone("child1");
		Bone childNone = new Bone("child2");
		Bone grandChildBone = new Bone("grandchild");
		
		bone.attachChild(childBone);
		bone.attachChild(childNone);
		
		childBone.attachChild(grandChildBone);
		
		assertTrue(bone.isChild(childBone));
		assertTrue(bone.isChild(childNone));
		assertFalse(bone.isChild(grandChildBone));
		
		assertTrue(childBone.isChild(grandChildBone));
	}
	

	public void testAddAnimation() {
		
		Bone bone = new Bone("test");
		
		try { 
			bone.addAnimation( null );
			fail();
		} catch( AssertionError e ) {
			// Expected error
		}
		
		try { 
			bone.addAnimation( new Animation("Animation", new KeyframeInterval( 0,0 ) ) );
		} catch( AssertionError e ) {
			fail();
		}
	}
	
	public void testSetAnimation() {
		
		Bone bone = new Bone("test");
		
		try { 
			bone.setAnimation( null );
			fail();
		} catch( AssertionError e ) {
			// Expected error
		}
		
		Quaternion quat = new Quaternion();
		quat.fromAngles( 90.0f, 90.0f, 90.0f );
		
		Quaternion quat2 = new Quaternion();
		quat2.fromAngles( 90.0f, 0.0f, 90.0f );
		
		bone.addKeyframe(  quat, 100, 10 );
		bone.addKeyframe(  quat2, 99, 9 );
		
		bone.addAnimation( new Animation( "animation1", new KeyframeInterval( 0, 0 ) ) );
		bone.addAnimation( new Animation( "animation2", new KeyframeInterval( 0, 1 ) ) );
		bone.addAnimation( new Animation( "animation3", new KeyframeInterval( 1, 1 ) ) );
		
		bone.setAnimation( "animation1" );
		
		assertEquals( "animation1", bone.actualAnimation.getName() );
		assertEquals( quat, bone.getLocalRotation() );
		assertEquals( quat, bone.nextKeyframeQuaternion );
		assertEquals( 100.0f, bone.actualKeyframeLength );
		assertEquals( 10.0f, bone.actualKeyframeWidth );
		assertEquals( 0, bone.actualKeyframeNumber );
		
		bone.setAnimation( "animation2" );
		
		assertEquals( "animation2", bone.actualAnimation.getName() );
		assertEquals( quat, bone.getLocalRotation() );
		assertEquals( quat2, bone.nextKeyframeQuaternion );
		assertEquals( 100.0f, bone.actualKeyframeLength );
		assertEquals( 10.0f, bone.actualKeyframeWidth );
		assertEquals( 0, bone.actualKeyframeNumber );
		
		bone.setAnimation( "animation3" );
		
		assertEquals( "animation3", bone.actualAnimation.getName() );
		assertEquals( quat2, bone.getLocalRotation() );
		assertEquals( quat2, bone.nextKeyframeQuaternion );
		assertEquals( 99.0f, bone.actualKeyframeLength );
		assertEquals( 9.0f, bone.actualKeyframeWidth );
		assertEquals( 1, bone.actualKeyframeNumber );
	}
	
	public void testUpdateAnimation() {
	
		Bone bone = new Bone("test");
		
		Quaternion quat = new Quaternion();
		quat.fromAngles( 90.0f, 90.0f, 90.0f );
		
		Quaternion quat2 = new Quaternion();
		quat2.fromAngles( 90.0f, 0.0f, 90.0f );
		
		Quaternion quat3 = new Quaternion();
		quat3.fromAngles( 45.0f, 0.0f, 90.0f );
		
		bone.addKeyframe(  quat, 100, 10 );
		bone.addKeyframe(  quat2, 50, 5 );
		bone.addKeyframe(  quat3, 25, 1 );
		
		bone.addAnimation( new Animation( "animation1", new KeyframeInterval( 0, 2 ), true, 0 ) );
		bone.setAnimation( "animation1" );
		
		assertEquals( "animation1", bone.actualAnimation.getName() );

		assertEquals( 0, bone.actualKeyframeNumber );
		assertEquals( quat, bone.getLocalRotation() );
		assertEquals( quat2, bone.nextKeyframeQuaternion );
		assertEquals( 100.0f, bone.actualKeyframeLength );
		assertEquals( 10.0f, bone.actualKeyframeWidth );
		
		bone.updateAnimation( 100.0f );
		
		assertEquals( 1, bone.actualKeyframeNumber );
		assertEquals( quat2, bone.getLocalRotation() );
		assertEquals( quat3, bone.nextKeyframeQuaternion );
		assertEquals( 50.0f, bone.actualKeyframeLength );
		assertEquals( 5.0f, bone.actualKeyframeWidth );
		
		bone.updateAnimation( 25.0f );
		bone.updateAnimation( 25.0f );
		
		assertEquals( 2, bone.actualKeyframeNumber );
		assertEquals( quat3, bone.getLocalRotation() );
		assertEquals( quat, bone.nextKeyframeQuaternion );
		assertEquals( 25.0f, bone.actualKeyframeLength );
		assertEquals( 1.0f, bone.actualKeyframeWidth );
		
		bone.updateAnimation( 25.0f );
		
		assertEquals( 0, bone.actualKeyframeNumber );
		assertEquals( quat, bone.getLocalRotation() );
		assertEquals( quat2, bone.nextKeyframeQuaternion );
		assertEquals( 100.0f, bone.actualKeyframeLength );
		assertEquals( 10.0f, bone.actualKeyframeWidth );
	}
}
